using SG3L_RAG.Application.Interfaces;
using SG3L_RAG.Domain.Entities;
using SG3L_RAG.Domain.Repositories;

namespace SG3L_RAG.Application.Services
{
    public class ConversationService : IConversationService
    {
        private readonly IRepository<Conversation> _conversationRepository;

        public ConversationService(IRepository<Conversation> conversationRepository)
        {
            _conversationRepository = conversationRepository;
        }

        public async Task<IEnumerable<Conversation>> GetCollectedByUserIdAsync(Guid userId)
        {
            var conversations = await _conversationRepository.GetAllAsync();
            return conversations.Where(c => c.UserId == userId && c.IsCollect);
        }

        public async Task<PagedResult<Conversation>> GetAllPagedAsync(int page = 1, int pageSize = 12)
        {
            var pageRequest = new PageRequest { Page = page, PageSize = pageSize };
            pageRequest.Validate();

            var conversations = await _conversationRepository.GetAllAsync();
            var orderedConversations = conversations.OrderByDescending(c => c.CreatedAt);

            return PagedResult<Conversation>.Create(orderedConversations, pageRequest.Page, pageRequest.PageSize);
        }

        public async Task<PagedResult<Conversation>> GetByUserIdPagedAsync(Guid userId, int page = 1, int pageSize = 12)
        {
            var pageRequest = new PageRequest { Page = page, PageSize = pageSize };
            pageRequest.Validate();

            var conversations = await _conversationRepository.GetAllAsync();
            var userConversations = conversations.Where(c => c.UserId == userId).OrderByDescending(c => c.CreatedAt);

            return PagedResult<Conversation>.Create(userConversations, pageRequest.Page, pageRequest.PageSize);
        }

        public async Task<Conversation?> GetByIdAsync(Guid id)
        {
            return await _conversationRepository.GetByIdAsync(id);
        }

        public async Task<IEnumerable<Conversation>> GetAllAsync()
        {
            return await _conversationRepository.GetAllAsync();
        }

        public async Task<Conversation> CreateAsync(Guid userId)
        {
            var conversation = Conversation.Create(userId);
            await _conversationRepository.AddAsync(conversation);
            return conversation;
        }

        public async Task<Conversation> CreateAsync(Guid userId, string title)
        {
            var conversation = Conversation.Create(userId, title);
            await _conversationRepository.AddAsync(conversation);
            return conversation;
        }

        public async Task UpdateAsync(Conversation conversation)
        {
            await _conversationRepository.UpdateAsync(conversation);
        }

        public async Task DeleteAsync(Guid id)
        {
            await _conversationRepository.DeleteAsync(id);
        }

        public async Task<IEnumerable<Conversation>> GetByUserIdAsync(Guid userId)
        {
            var conversations = await _conversationRepository.GetAllAsync();
            return conversations.Where(c => c.UserId == userId);
        }

        public async Task<Conversation?> GetLatestByUserIdAsync(Guid userId)
        {
            var conversations = await GetByUserIdAsync(userId);
            return conversations.OrderByDescending(c => c.CreatedAt).FirstOrDefault();
        }

        public async Task<IEnumerable<Conversation>> GetRecentConversationsAsync(Guid userId, int count = 10)
        {
            var conversations = await GetByUserIdAsync(userId);
            return conversations.OrderByDescending(c => c.CreatedAt).Take(count);
        }

        public async Task AddMessageAsync(Guid conversationId, Message message)
        {
            var conversation = await _conversationRepository.GetByIdAsync(conversationId);
            if (conversation != null)
            {
                conversation.AddMessage(message);
                await _conversationRepository.UpdateAsync(conversation);
            }
        }

        public async Task<int> GetMessageCountAsync(Guid conversationId)
        {
            var conversation = await _conversationRepository.GetByIdAsync(conversationId);
            return conversation?.Messages.Count ?? 0;
        }

        public async Task SetCollectAsync(Guid conversationId, bool isCollect)
        {
            var conversation = await _conversationRepository.GetByIdAsync(conversationId);
            if (conversation != null)
            {
                conversation.SetCollect(isCollect);
                await _conversationRepository.UpdateAsync(conversation);
            }
        }
    }
}
